﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Printing;
using System.Windows.Forms;

namespace Sales
{
   /// <summary>
    /// PrintDocument.PrintPage的委托定义
    /// </summary>
    public delegate void PrintPageDelegate(Object obj, System.Drawing.Printing.PrintPageEventArgs ev);


    interface IPrinterPageSetting
    {
        /// <summary>
        /// 获取或设置打印文档
        /// </summary>
        System.Drawing.Printing.PrintDocument PrintDocument
        {
            get;
            set;
        }


        /// <summary>
        /// 关联一个方法，目的是让具体的打印由实例化者来操作
        /// 如PrinterPageSetting1.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
        /// </summary>
        PrintPageDelegate PrintPageValue
        {
            get;
            set;
        }

        event PrintPageDelegate PrintPage;


        /// <summary>
        /// 显示页面设置对话框，并返回PageSettings
        /// </summary>
        /// <returns></returns>
        System.Drawing.Printing.PageSettings ShowPageSetupDialog();

        /// <summary>
        /// 显示打印机设置对话框，并返回PrinterSettings
        /// </summary>
        /// <returns></returns>
        System.Drawing.Printing.PrinterSettings ShowPrintSetupDialog();

        /// <summary>
        /// 显示打印预览对话框
        /// </summary>
        void ShowPrintPreviewDialog();

    }

//WIN打印

/// <summary>
    /// WinForm下的打印纸张设置、打印机设置、打印预览对话框。
    /// </summary>
    public class WinPrinterPageSetting : IPrinterPageSetting
    {
        //把PrintPage委托声明为类的一个成员变量
        private PrintPageDelegate _printPageValue;
        // 打印文档
        private PrintDocument _printDocument;

        #region 构造函数
        public WinPrinterPageSetting()
            : this(null)
        {

        }

        /// <summary>
        /// 使用printDocument来初始化类的新实例，当printDocument为null时自动创建一个printDocument的实例
        /// </summary>
        /// <param name="printDocument"></param>
        public WinPrinterPageSetting(PrintDocument printDocument)
        {
            if (printDocument != null)
            {
                _printDocument = printDocument;
            }
            else
            {
                _printDocument = new PrintDocument();
            }
        }
        #endregion


        #region IPrinterPageSetting 成员

        /// <summary>
        /// 获取或设置打印文档
        /// </summary>
        public PrintDocument PrintDocument
        {
            get
            {
                return this._printDocument;
            }
            set
            {
                this._printDocument = value;
            }
        }

        /// <summary>
        /// 一定要实例化此类后在调用打印/预览之前设置此属性，使之关联一个方法，目的是让具体的打印由实例化者来操作
        /// 如PrinterPageSetting1.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
        /// </summary>
        public PrintPageDelegate PrintPageValue
        {
            set
            {
                //初始委托变量，关联方法
                _printPageValue = value;

                //if (_printDocument == null)
                //{
                //    throw new Exception("关联的打印文档不能为空！");
                //}
                _printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this._printPageValue);
            }
            get
            {
                return _printPageValue;
            }
        }

        public event PrintPageDelegate PrintPage
        {
            add
            {
                _printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(value);
                _printPageValue = value;
            }
            remove
            {
                _printDocument.PrintPage -= new System.Drawing.Printing.PrintPageEventHandler(value);
                _printPageValue = null;
            } 

        }

        /// <summary>
        /// 显示页面设置对话框，并返回PageSettings
        /// </summary>
        /// <returns></returns>
        public PageSettings ShowPageSetupDialog()
        {
            return ShowPageSetupDialog(this._printDocument);
        }

        /// <summary>
        /// 显示打印机设置对话框，并返回PrinterSettings
        /// </summary>
        /// <returns></returns>
        public PrinterSettings ShowPrintSetupDialog()
        {
            return ShowPrintSetupDialog(this._printDocument);
        }

        /// <summary>
        /// 显示打印预览对话框
        /// </summary>
        public void ShowPrintPreviewDialog()
        {
            ShowPrintPreviewDialog(this._printDocument);
        }

        #endregion

 

        //***************注意：以下几个对话框方法可以独立使用***************
        #region 页面设置对话框 protected virtual PageSettings ShowPageSetupDialog(PrintDocument printDocument)
        /// <summary>
        /// 页面设置对话框，可以独立使用
        /// </summary>
        /// <param name="printDocument"></param>
        /// <returns></returns>
        protected virtual PageSettings ShowPageSetupDialog(PrintDocument printDocument)
        {
            //声明返回值的PageSettings
            PageSettings ps = new PageSettings();

            if (printDocument == null)
            {
                throw new Exception("关联的打印文档不能为空！");
            }

            try
            {
                //申明并实例化PageSetupDialog
                PageSetupDialog psDlg = new PageSetupDialog();

                //相关文档及文档页面默认设置
                psDlg.Document = printDocument;
                psDlg.PageSettings = printDocument.DefaultPageSettings;

                //显示对话框
                DialogResult result = psDlg.ShowDialog();
                if (result == DialogResult.OK)
                {
                    ps = psDlg.PageSettings;
                    printDocument.DefaultPageSettings = psDlg.PageSettings;
                }

            }
            catch (System.Drawing.Printing.InvalidPrinterException e)
            {
                MessageBox.Show("未安装打印机，请进入系统控制面版添加打印机！", "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            return ps;
        }
        #endregion


        #region 打印设置对话框 protected virtual PrinterSettings ShowPrintSetupDialog(PrintDocument printDocument)
        /// <summary>
        /// 打印设置对话框，可以独立使用
        /// </summary>
        /// <param name="printDocument"></param>
        /// <returns></returns>
        protected virtual PrinterSettings ShowPrintSetupDialog(PrintDocument printDocument)
        {
            //声明返回值的PrinterSettings
            PrinterSettings ps = new PrinterSettings();
            if (printDocument == null)
            {
                throw new Exception("关联的打印文档不能为空！");
            }

            try
            {
                //申明并实例化PrintDialog
                PrintDialog pDlg = new PrintDialog();

                //可以选定页
                pDlg.AllowSomePages = true;

                //指定打印文档
                pDlg.Document = printDocument;

                //显示对话框
                DialogResult result = pDlg.ShowDialog();
                if (result == DialogResult.OK)
                {
                    //保存打印设置
                    ps = pDlg.PrinterSettings;
                    //打印
                    printDocument.Print();
                }

            }
            catch (System.Drawing.Printing.InvalidPrinterException e)
            {
                MessageBox.Show("未安装打印机，请进入系统控制面版添加打印机！", "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            return ps;
        }
        #endregion


        #region 打印预览对话框 protected virtual void ShowPrintPreviewDialog(PrintDocument printDocument)
        /// <summary>
        /// 打印预览对话框，可以独立使用
        /// </summary>
        /// <param name="printDocument"></param>
        /// <returns></returns>
        /// <remarks>
        protected virtual void ShowPrintPreviewDialog(PrintDocument printDocument)
        {
            if (printDocument == null)
            {
                throw new Exception("关联的打印文档不能为空！");
            }

            try
            {
                //申明并实例化PrintPreviewDialog
                PrintPreviewDialog ppDlg = new PrintPreviewDialog();

                //指定打印文档
                ppDlg.Document = printDocument;


                //显示对话框
                DialogResult result = ppDlg.ShowDialog();
                if (result == DialogResult.OK)
                {
                    //...
                }

            }
            catch (System.Drawing.Printing.InvalidPrinterException e)
            {
                MessageBox.Show("未安装打印机，请进入系统控制面版添加打印机！", "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
        #endregion

    }

//WEB打印

/// <summary>
    /// WebForm下的打印纸张设置、打印机设置、打印预览对话框。
    /// </summary>

    public class WebPrinterPageSetting : IPrinterPageSetting
    {
        public WebPrinterPageSetting()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }


        #region IPrinterPageSetting 成员

        public System.Drawing.Printing.PrintDocument PrintDocument
        {
            get
            {
                // TODO:  添加 WebPrinterPageSetting.PrintDocument getter 实现
                return null;
            }
            set
            {
                // TODO:  添加 WebPrinterPageSetting.PrintDocument setter 实现
            }
        }

        public PrintPageDelegate PrintPageValue
        {
            get
            {
                // TODO:  添加 WebPrinterPageSetting.PrintPage getter 实现
                return null;
            }
            set
            {
                // TODO:  添加 WebPrinterPageSetting.PrintPage setter 实现
            }
        }

       
        public event PrintPageDelegate PrintPage;

        public System.Drawing.Printing.PageSettings ShowPageSetupDialog()
        {
            // TODO:  添加 WebPrinterPageSetting.ShowPageSetupDialog 实现
            return null;
        }

        public System.Drawing.Printing.PrinterSettings ShowPrintSetupDialog()
        {
            // TODO:  添加 WebPrinterPageSetting.ShowPrintSetupDialog 实现
            return null;
        }

        public void ShowPrintPreviewDialog()
        {
            // TODO:  添加 WebPrinterPageSetting.ShowPrintPreviewDialog 实现
        }

        #endregion

    }

//将WinPrinterPageSetting与WebPrinterPageSetting合二为一。
    //在类的构造函数中增加自动判断Windows模式还是Web模式,同时也提供PrintMode属性可以让用户修改

    /// <summary>
    /// 打印方式
    /// </summary> 
    public enum PrintModeFlag
    {
        /// <summary>
        /// Windows窗口打印方式
        /// </summary>
        Win
         ,
        /// <summary>
        /// Web窗口打印方式
        /// </summary>
        Web
    }


    /// <summary>
    /// 封装页面设置、打印机设置、打印预览，适合于Window和Asp.Net。
    /// </summary>
    public class PrinterPageSetting : IPrinterPageSetting
    {
        //申明一个封装页面设置、打印机设置、打印预览的接口
        private IPrinterPageSetting _printerPageSetting;

        //打印方式
        private PrintModeFlag _printModeFlag;

        public PrintModeFlag PrintMode
        {
            get
            {
                return this._printModeFlag;
            }
            set
            {
                this._printModeFlag = value;
                //运用了抽象模式，创建接口对象的新实例，使其指象真正的实现其接口的对象
                if (this._printModeFlag == PrintModeFlag.Win)
                {
                    _printerPageSetting = new WinPrinterPageSetting();
                }
                else if (this._printModeFlag == PrintModeFlag.Web)
                {
                    _printerPageSetting = new WebPrinterPageSetting();
                }
            }
        }


        /// <summary>
        /// 获取或设置打印文档
        /// </summary>
        public PrintDocument PrintDocument
        {
            get
            {
                return _printerPageSetting.PrintDocument;
            }
            set
            {
                _printerPageSetting.PrintDocument = value;
            }
        }


        /// <summary>
        /// 一定要实例化此类后在调用打印/预览初始此变量，使之关联一个方法，目的是让具体的打印由实例化者来操作
        /// 如PrinterPageSetting1.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
        /// </summary>
        public PrintPageDelegate PrintPageValue
        {
            set
            {
                _printerPageSetting.PrintPageValue = value;
            }
            get
            {
                return _printerPageSetting.PrintPageValue;
            }
        }

        public event PrintPageDelegate PrintPage
        {
            add
            {
                _printerPageSetting.PrintPage += new PrintPageDelegate(value);
            }
            remove
            {
                _printerPageSetting.PrintPage -= new PrintPageDelegate(value);
            }
        }

 

        #region 构造函数
        /// <summary>
        ///  封装页面设置、打印机设置、打印预览，适合于Window和Asp.Net，Web方式下请在配置文件中增加键PrintMode及值Web，也可以实例化后设置PrintMode属性为PrintModeFlag.Web。
        /// </summary>
        public PrinterPageSetting()
            : this(null)
        {

        }

        /// <summary>
        ///  封装页面设置、打印机设置、打印预览，适合于Window和Asp.Net，Web方式下请在配置文件中增加键PrintMode及值Web，也可以实例化后设置PrintMode属性为PrintModeFlag.Web。
        /// </summary>
        /// <param name="printDocument"></param>
        public PrinterPageSetting(PrintDocument printDocument)
        {
            string strPrintMode = "";

            //配置文件中键PrintMode
            strPrintMode = System.Configuration.ConfigurationSettings.AppSettings["PrintMode"];

            if (strPrintMode == null)
            {
                //默认为Win方式  
                strPrintMode = "Win";
            }

            //配置文件中键PrintMode的值Win/Web
            if (strPrintMode.ToUpper() == "WIN")
            {
                this.PrintMode = PrintModeFlag.Win;
            }
            else
            {
                this.PrintMode = PrintModeFlag.Web;
            }

            /*  //配置文件中添加键值的写法
             <?xml version="1.0" encoding="utf-8" ?>
             <configuration>
              <appSettings>
                <add key="PrintMode" value="Web"/>
              </appSettings>
             </configuration>
            */
            if (printDocument != null)
            {
                _printerPageSetting.PrintDocument = printDocument;
            } 

          

        }
        #endregion

        /// <summary>
        /// 显示页面设置对话框，并返回PageSettings
        /// </summary>
        /// <returns></returns>
        public PageSettings ShowPageSetupDialog()
        {
            return _printerPageSetting.ShowPageSetupDialog();
        }

        /// <summary>
        /// 显示打印机设置对话框，并返回PrinterSettings
        /// </summary>
        /// <returns></returns>
        public PrinterSettings ShowPrintSetupDialog()
        {
            return _printerPageSetting.ShowPrintSetupDialog();
        }

        /// <summary>
        /// 显示打印预览对话框
        /// </summary>
        public void ShowPrintPreviewDialog()
        {
            _printerPageSetting.ShowPrintPreviewDialog();
        }

    }
}
